/**
 * @file app\tasks\mobus\inc\mobus.h
 *
 * Copyright (C) 2023
 *
 * mobus.h is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * @author HinsShum hinsshum@qq.com
 *
 * @encoding utf-8
 */
#ifndef __MOBUS_H
#define __MOBUS_H

#ifdef __cplusplus
extern "C" {
#endif

/*---------- includes ----------*/
#include "protocol_mobus.h"
#include "serial_transport_level.h"
#include "soft_timer.h"
#include "storage.h"
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
/*---------- type define ----------*/
    typedef struct mobus_device* mobus_device_t;

    enum mobus_login {
        MOBUS_LOGGING_IN,
        MOBUS_LOGGED_IN,
    };

    struct mobus_channel_device {
        mobus_device_type_t device_type;
        bool (*evt_cb)(mobus_device_t self, protocol_mobus_evt_t evt, mobus_ack_result_t* result);
    };

    struct mobus_device {
        serial_transport_t mobus;
        mobus_device_type_t device_type;
        enum mobus_login login;
        uint8_t native_address;
        uint8_t version;
        /* mobus channels */
        uint8_t channel_nums;
        mobus_device_type_t device_channl_type[CONFIG_STORAGE_MOBUS_CHANNEL_NUMS];
        /* mobus device ops */
        void (*init)(mobus_device_t self, serial_transport_t mobus);
        void (*get_device_data)(mobus_device_t self);
        void (*deinit)(mobus_device_t self);
        void (*req_access_to_mobus_network)(mobus_device_t self);
        void (*upgrade)(mobus_device_t self, uint8_t sync);
        void (*ack)(mobus_device_t self, mobus_frame_type_t type, mobus_ack_result_t result);
        void (*command)(mobus_device_t self, uint8_t sub_channel, uint8_t* param, uint8_t length);
        void (*multicast)(mobus_device_t self, uint16_t uid, uint8_t command, uint8_t sub_command, uint8_t* param, uint8_t length);
        void (*get_parameters)(mobus_device_t self, uint8_t sub_channel, uint8_t start, uint8_t* pbuf, uint8_t numbers);
        void (*set_parameters)(mobus_device_t self, uint8_t sub_channel, uint8_t start, const uint8_t* pbuf, uint8_t numbers);
        void (*config_device)(mobus_device_t self, uint8_t channel, uint8_t devaddr, uint16_t devtype, uint8_t number_of_channels);
        void (*report_status)(mobus_device_t self, uint8_t channel);
        void (*report_information)(mobus_device_t self, uint8_t channel);
        void (*restore_factory)(mobus_device_t self, uint8_t sync);
        void (*factory_test)(mobus_device_t self, uint8_t* param, uint8_t length);
        void (*passthrough)(mobus_device_t self, uint8_t sub_channel, mobus_frame_type_t type, const uint8_t* pdata, uint16_t length);
        bool (*evt_cb)(mobus_device_t self, protocol_mobus_evt_t evt, mobus_ack_result_t* result);
    };
    /*---------- variable prototype ----------*/
    /*---------- function prototype ----------*/

#ifdef __cplusplus
}
#endif
#endif /* __MOBUS_H */
